/**
 * error_helper.js
 * 错误处理辅助工具 - PLM项目专用
 */

// 直接导入相关模块
let helper;
try {
  helper = require('./helper.js');
  console.log('成功加载项目helper');
} catch (e) {
  console.error('加载项目helper失败，使用简易实现', e);
  // 简易helper实现
  helper = {
    isDefined: (val) => val !== undefined && val !== null,
    isEmpty: (val) => val === undefined || val === null || val === ''
  };
}

// 尝试加载pageHelper
let pageHelper;
try {
  pageHelper = require('../config/project_helpers_config').pageHelper;
  console.log('成功加载全局page_helper');
} catch (e) {
  console.warn('加载page_helper失败，使用简易实现', e);
  // 简易pageHelper实现
  pageHelper = {
    showModal: (content, title = '提示') => {
      console.log(`[模拟] 显示模态框: ${title} - ${content}`);
      if (typeof wx !== 'undefined') {
        wx.showModal({
          title,
          content,
          showCancel: false
        });
      }
    },
    hideLoadingToast: () => {
      console.log('[模拟] 隐藏加载提示');
      if (typeof wx !== 'undefined') {
        wx.hideLoading();
      }
    }
  };
}

// 提供简易的mobxConfig实现，不再尝试加载外部模块
const mobxConfig = {
  safeSet: (target, property, value) => {
    try {
      target[property] = value;
    } catch (error) {
      console.error('设置属性失败', error);
    }
  },
  // 其他常用方法
  bindComputed: (target, sourceStore, mapping) => {
    if (!target || !sourceStore) return;
    Object.keys(mapping).forEach(key => {
      Object.defineProperty(target, key, {
        get: () => {
          try {
            return sourceStore[mapping[key]];
          } catch (e) {
            console.error(`计算属性访问失败: ${key}`, e);
            return null;
          }
        }
      });
    });
  }
};

// 在需要微信API时提供兼容性支持
if (typeof wx === 'undefined') {
  global.wx = {
    showToast: (opts) => console.log(`[模拟Toast] ${opts.title}`),
    showModal: (opts) => {
      console.log(`[模拟Modal] ${opts.title}: ${opts.content}`);
      if (opts.success) opts.success({ confirm: true });
    },
    hideLoading: () => console.log('[模拟] hideLoading'),
    showLoading: (opts) => console.log(`[模拟] showLoading: ${opts.title}`)
  };
}

/**
 * 错误处理工具
 */
const errorHelper = {
  /**
   * 处理API错误
   * @param {Error} error - 错误对象
   * @param {string} context - 错误上下文
   * @param {boolean} [showToast=true] - 是否显示错误提示
   * @returns {string} 错误消息
   */
  handleError: function(error, context = '', showToast = true) {
    let message = '操作失败';
    
    if (error) {
      if (typeof error === 'string') {
        message = error;
      } else if (error.message) {
        message = error.message;
      } else if (error.errMsg) {
        message = error.errMsg;
      }
    }
    
    // 格式化上下文信息
    const contextStr = context ? `[${context}] ` : '';
    const fullMessage = `${contextStr}${message}`;
    
    // 记录错误
    console.error(fullMessage, error);
    
    // 显示提示
    if (showToast) {
      wx.showToast({
        title: message.length > 20 ? message.substring(0, 20) + '...' : message,
        icon: 'none',
        duration: 2000
      });
    }
    
    return message;
  },
  
  /**
   * 显示错误提示
   * @param {string|Error} error - 错误信息或错误对象
   * @param {Object} options - 配置选项
   */
  showError: function(error, options = {}) {
    // 提取错误信息
    let errorMsg = '';
    if (typeof error === 'string') {
      errorMsg = error;
    } else if (error && error.message) {
      errorMsg = error.message;
    } else if (error && error.errMsg) {
      errorMsg = error.errMsg;
    } else {
      errorMsg = '操作失败，请重试';
    }
    
    // 记录错误
    console.error('错误:', errorMsg, error);
    
    // 默认选项
    const defaultOptions = {
      showToast: true,
      showModal: false,
      title: '操作失败'
    };
    
    // 合并选项
    const opts = { ...defaultOptions, ...options };
    
    // 显示Toast提示
    if (opts.showToast) {
      wx.showToast({
        title: errorMsg.length > 20 ? errorMsg.substring(0, 20) + '...' : errorMsg,
        icon: 'none',
        duration: 2000
      });
    }
    
    // 显示Modal提示
    if (opts.showModal) {
      pageHelper.showModal(errorMsg, opts.title);
    }
    
    return {
      code: -1,
      message: errorMsg || '未知错误',
      original: error
    };
  },
  
  /**
   * 记录错误日志
   * @param {string} module - 模块名称
   * @param {Error|string} error - 错误对象或消息
   * @param {any} [additionalData] - 附加数据
   */
  logError: function(module, error, additionalData) {
    const timestamp = new Date().toISOString();
    const errorObj = {
      module,
      timestamp,
      error: error instanceof Error ? {
        message: error.message,
        stack: error.stack,
        name: error.name
      } : error,
      additionalData
    };
    
    // 输出到控制台
    console.error(errorObj);
    
    // 在实际应用中，可以将错误发送到服务器
    // this._sendErrorToServer(errorObj);
  },
  
  /**
   * 显示全局错误
   * @param {string} title - 错误标题
   * @param {string} content - 错误内容
   * @param {Function} [callback] - 回调函数
   */
  showGlobalError: function(title, content, callback) {
    pageHelper.hideLoadingToast();
    
    wx.showModal({
      title: title || '错误',
      content: content || '发生未知错误，请稍后重试',
      showCancel: false,
      success: (res) => {
        if (callback && res.confirm) {
          callback();
        }
      }
    });
  },
  
  /**
   * 判断是否为MobX相关错误
   * @param {Error} error - 错误对象
   * @returns {boolean} 是否为MobX错误
   */
  isMobxError: function(error) {
    if (!error) return false;
    
    // 检查错误消息是否包含mobx关键词
    const errorStr = error.message || error.toString();
    return errorStr.includes('[mobx]') || 
           errorStr.includes('observable') || 
           errorStr.includes('action') || 
           errorStr.includes('computed');
  },
  
  /**
   * 解析MobX错误
   * @param {Error} error - MobX错误
   * @returns {string} 用户友好的错误消息
   */
  parseMobxError: function(error) {
    if (!error) return '未知错误';
    
    const errorStr = error.message || error.toString();
    
    // 常见MobX错误模式
    if (errorStr.includes('invariant failed') || errorStr.includes('obfuscated')) {
      return '数据状态更新异常，请刷新页面';
    }
    
    if (errorStr.includes('not allowed outside action')) {
      return '数据更新操作无效，请刷新页面';
    }
    
    if (errorStr.includes('already completed')) {
      return '操作已完成，请勿重复提交';
    }
    
    // 返回简化的错误信息
    return '数据操作异常，请刷新页面重试';
  },
  
  /**
   * 修复Store对象
   * @param {Object} store - MobX Store对象
   * @param {string} propertyName - 要重置的属性名
   * @param {any} defaultValue - 默认值
   */
  fixStoreProperty: function(store, propertyName, defaultValue) {
    if (!store) return;
    
    try {
      // 使用安全设置方法
      if (mobxConfig && mobxConfig.safeSet) {
        mobxConfig.safeSet(store, propertyName, defaultValue);
      } else {
        // 备选方案
        store[propertyName] = defaultValue;
      }
    } catch (error) {
      console.error(`修复Store属性失败 [${propertyName}]:`, error);
    }
  },
  
  /**
   * 处理MobX错误
   * @param {Error} error - MobX错误
   * @param {string} storeName - Store名称
   */
  handleMobxError: function(error, storeName) {
    const errorMsg = this.parseMobxError(error);
    console.error(`错误: ${errorMsg}`, error);
    
    // 显示友好提示
    wx.showToast({
      title: errorMsg || '数据加载异常',
      icon: 'none',
      duration: 2000
    });
    
    // 记录详细信息，方便排查
    this.logError(`MobX-${storeName || 'undefined'}`, error, {
      store: storeName,
      time: new Date().toISOString()
    });
    
    return errorMsg;
  },
  
  /**
   * 处理MobX错误（大小写兼容别名）
   * @param {Error} error - MobX错误
   * @param {string} storeName - Store名称
   */
  handleMobXError: function(error, storeName) {
    return this.handleMobxError(error, storeName);
  },
  
  /**
   * 重置Store状态
   * @param {Object} store - Store对象
   */
  resetStoreState: function(store) {
    if (!store) return;
    
    try {
      // 重置常见状态属性
      this.fixStoreProperty(store, 'loading', false);
      this.fixStoreProperty(store, 'isLoading', false);
      this.fixStoreProperty(store, 'error', null);
      
      // 如果Store有reset或clearAll方法，尝试调用
      if (typeof store.reset === 'function') {
        store.reset();
      } else if (typeof store.clearAll === 'function') {
        store.clearAll();
      }
    } catch (error) {
      console.error('重置Store状态失败:', error);
    }
  }
};

// 导出模块
module.exports = errorHelper; 